package com.zyj.juc;

import sun.security.krb5.internal.Ticket;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @program: JVMDemo
 * @ClassName SynchronizedTest
 * @author: YaJun
 * @Date: 2021 - 12 - 16 - 16:32
 * @Package: com.zyj.juc
 * @Description:
 */
public class SynchronizedTest {
    public static class CustomDemoEntity {
        private int flag = 1;

        private Lock lock = new ReentrantLock();

        private Condition c1 = lock.newCondition();
        private Condition c2 = lock.newCondition();
        private Condition c3 = lock.newCondition();

        public void printA(int loop){
            lock.lock();
            try {
                while (flag != 1){
                    c1.await();
                }
                for (int i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName() + "::第" + loop + "次循环::" + flag);
                }
                flag = 2;
                c2.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }

        public void printB(int loop){
            lock.lock();
            try {
                while (flag != 2){
                    c2.await();
                }
                for (int i = 0; i < 10; i++) {
                    System.out.println(Thread.currentThread().getName() + "::第" + loop + "次循环::" + flag);
                }
                flag = 3;
                c3.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }

        public void printC(int loop){
            lock.lock();
            try {
                while (flag != 3){
                    c3.await();
                }
                for (int i = 0; i < 15; i++) {
                    System.out.println(Thread.currentThread().getName() + "::第" + loop + "次循环::" + flag);
                }
                flag = 1;
                c1.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }

        public static void main(String[] args) {
            CustomDemoEntity demoEntity = new CustomDemoEntity();

            new Thread(() -> {
                for (int i = 0; i < 10; i++) {
                    demoEntity.printA(i);
                }
            }, "AA").start();

            new Thread(() -> {
                for (int i = 0; i < 10; i++) {
                    demoEntity.printB(i);
                }
            }, "BB").start();

            new Thread(() -> {
                for (int i = 0; i < 10; i++) {
                    demoEntity.printC(i);
                }
            }, "CC").start();
        }

    }




}
